﻿//using System;
//using System.Net;
//using System.Windows;
//using System.Windows.Controls;
//using System.Windows.Documents;
//using System.Windows.Ink;
//using System.Windows.Input;
//using System.Windows.Media;
//using System.Windows.Media.Animation;
//using System.Windows.Shapes;
//using System.Collections.Generic;
//using System.Windows.Controls.Primitives;
//using System.Collections;
//using System.Linq;
//using System.ComponentModel;

//namespace Microsoft.WVB.UI
//{

//    public enum ConcurrenceMode
//    {
//        Exclusive,
//        Inclusive
//    }

//    public enum WindowCommand
//    {
//        Open,
//        Close,
//        OpenClose
//    }

//    public class LayoutGroup
//    {
//        public String Name { get; set; }
//        public ConcurrenceMode Mode { get; set; }
//    }

//    public static class AuthLayoutService
//    {
//        public static object GetCommandHandled(DependencyObject element)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            return element.GetValue(CommandHandledProperty);
//        }

//        public static void SetCommandHandled(DependencyObject element, object value)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            element.SetValue(CommandHandledProperty, value);
//        }

//        public static readonly DependencyProperty CommandHandledProperty = null;

//        public static object GetCommandGroup(DependencyObject element)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            return element.GetValue(CommandGroupProperty);
//        }

//        public static void SetCommandGroup(DependencyObject element, object value)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            element.SetValue(CommandGroupProperty, value);
//        }

//        public static readonly DependencyProperty CommandGroupProperty = null;

//        public static object GetCommandTarget(DependencyObject element)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            return element.GetValue(CommandTargetProperty);
//        }

//        public static void SetCommandTarget(DependencyObject element, object value)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            element.SetValue(CommandTargetProperty, value);
//        }

//        public static readonly DependencyProperty CommandTargetProperty = null;

//        public static object GetCommandSink(DependencyObject element)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            return element.GetValue(CommandSinkProperty);
//        }

//        public static void SetCommandSink(DependencyObject element, object value)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            element.SetValue(CommandSinkProperty, value);
//        }

//        public static readonly DependencyProperty CommandSinkProperty = null;

//        public static object GetCommandMode(DependencyObject element)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            return element.GetValue(CommandModeProperty);
//        }

//        public static void SetCommandMode(DependencyObject element, object value)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            element.SetValue(CommandModeProperty, value);
//        }

//        public static readonly DependencyProperty CommandModeProperty = null;

//        private static Dictionary<ButtonBase, Type> CmdTargetDic = null;
//        private static Dictionary<ButtonBase, WindowCommand> BtnCmdDic = null;
//        private static Dictionary<LayoutGroup, List<Type>> GrpTypeDic = null;
//        private static Dictionary<Type, UIElement> CmdSinkDic = null;

//        static AuthLayoutService()
//        {
//            // we expect Buttons to be Unique across the application - by default it is.
//            BtnCmdDic = new Dictionary<ButtonBase, WindowCommand>();
//            CmdTargetDic = new Dictionary<ButtonBase, Type>();
//            GrpTypeDic = new Dictionary<LayoutGroup, List<Type>>(new LayoutGroupComparer());

//            // TOD: Data for testing - we need to come up with something better to initialize Groups
//            GrpTypeDic.Add(new LayoutGroup() { Name = "Auth", Mode = ConcurrenceMode.Exclusive }, new List<Type>());
//            // Assumption here that there will be only one type of control/UserControl displayed in the application
//            // So, we cannot have two WindowContainer in the application hosting the same Control/UserControl
//            CmdSinkDic = new Dictionary<Type, UIElement>();
//            CommandHandledProperty = DependencyProperty.RegisterAttached("CommandHandled", typeof(bool), typeof(AuthLayoutService), null);
//            CommandGroupProperty = DependencyProperty.RegisterAttached("CommandGroup", typeof(String), typeof(AuthLayoutService), new PropertyMetadata(new PropertyChangedCallback(OnCommandGroupChanged)));
//            CommandTargetProperty = DependencyProperty.RegisterAttached("CommandTarget", typeof(String), typeof(AuthLayoutService), new PropertyMetadata(new PropertyChangedCallback(OnCommandTargetChanged)));
//            CommandSinkProperty = DependencyProperty.RegisterAttached("CommandSink", typeof(String), typeof(AuthLayoutService), new PropertyMetadata(new PropertyChangedCallback(OnCommandSinkChanged)));
//            CommandModeProperty = DependencyProperty.RegisterAttached("CommandMode", typeof(String), typeof(AuthLayoutService), new PropertyMetadata(new PropertyChangedCallback(OnCommandModeChanged)));
//        }

//        static void OnButtonClick(object sender, RoutedEventArgs e)
//        {
//            UIElement uiElement = null;
//            ButtonBase tempBtn = sender as ButtonBase;
//            bool handled = (bool)AuthLayoutService.GetCommandHandled(sender as DependencyObject);

//            if ((tempBtn != null) && (!handled))
//            {
//                if (CmdTargetDic.ContainsKey(sender as ButtonBase))
//                {
//                    Type t = CmdTargetDic[sender as ButtonBase];
//                    LayoutGroup lgroup = null;

//                    if (CmdSinkDic.ContainsKey(t))
//                    {
//                        uiElement = CmdSinkDic[t];
//                    }

//                    if (uiElement != null)
//                    {
//                        if (((BtnCmdDic[tempBtn] == WindowCommand.Open) || (BtnCmdDic[tempBtn] == WindowCommand.OpenClose)))
//                        {
//                            foreach (LayoutGroup grp in GrpTypeDic.Keys)
//                            {
//                                if (GrpTypeDic[grp].Contains(t))
//                                {
//                                    lgroup = grp;
//                                    break;
//                                }
//                            }

//                            if (lgroup.Mode == ConcurrenceMode.Exclusive)
//                            {
//                                foreach (Type type in GrpTypeDic[lgroup])
//                                {
//                                    if ((CmdSinkDic.ContainsKey(type)) && (!type.Equals(t)))
//                                    {
//                                        UIElement ui = CmdSinkDic[type];
//                                        ui.Visibility = Visibility.Collapsed;
//                                    }
//                                }
//                            }
//                        }

//                        if (uiElement.Visibility == Visibility.Visible)
//                        {
//                            if ((BtnCmdDic[tempBtn] == WindowCommand.Close) || (BtnCmdDic[tempBtn] == WindowCommand.OpenClose))
//                                uiElement.Visibility = Visibility.Collapsed;
//                        }
//                        else
//                        {
//                            if ((BtnCmdDic[tempBtn] == WindowCommand.Open) || (BtnCmdDic[tempBtn] == WindowCommand.OpenClose))
//                                uiElement.Visibility = Visibility.Visible;
//                        }
//                    }
//                }
//            }
//            AuthLayoutService.SetCommandHandled(sender as DependencyObject, false);
//        }

//        static void OnCommandGroupChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
//        {

//        }

//        static void OnCommandTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
//        {
//            ButtonBase tempButton = d as ButtonBase;

//            Type t = Type.GetType((string)e.NewValue);
//            // CommandMode needs to be set before CommandTarget
//            WindowCommand cmdMode = (WindowCommand)Enum.Parse(typeof(WindowCommand), (string)AuthLayoutService.GetCommandMode(d), true);

//            if ((tempButton != null) && (t != null))
//            {
//                ((ButtonBase)d).Click += new RoutedEventHandler(OnButtonClick);
//                BtnCmdDic.Add(d as ButtonBase, cmdMode);

//                if (!CmdTargetDic.ContainsKey(d as ButtonBase))
//                {
//                    CmdTargetDic.Add(d as ButtonBase, t);
//                }
//            }
//        }

//        static void OnCommandSinkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
//        {
//            UIElement tempUI = d as UIElement;
//            // workaround because of a Bug #21128 - Attached property cannot be something else that String
//            Type t = Type.GetType((string)e.NewValue);

//            // CommandGroup needs to be set before CommandSink
//            String cmdGroup = (String)AuthLayoutService.GetCommandGroup(d);

//            IEnumerable<LayoutGroup> selectedGrp = (from c in GrpTypeDic.Keys
//                                                    where c.Name == cmdGroup
//                                                    select c);

//            if ((tempUI != null) && (!String.IsNullOrEmpty(cmdGroup)) && t != null)
//            {
//                if (selectedGrp.Count() == 0)
//                {
//                    throw new ArgumentOutOfRangeException("The group specified is not valid or not registered");
//                }
//                else if (selectedGrp.Count() == 1)
//                {
//                    GrpTypeDic[selectedGrp.First()].Add(t);
//                }

//                if (!CmdSinkDic.ContainsKey(t))
//                {
//                    CmdSinkDic.Add(t, d as UIElement);
//                }
//            }
//        }

//        static void OnCommandModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
//        {

//        }

//        public static void RegisterGroup(LayoutGroup lgroup)
//        {
//            if (!GrpTypeDic.ContainsKey(lgroup))
//            {
//                GrpTypeDic.Add(lgroup, new List<Type>());
//            }
//        }

//        public static void UnRegisterGroup(LayoutGroup group)
//        {
//            if (GrpTypeDic.ContainsKey(group))
//            {
//                GrpTypeDic.Remove(group);
//            }
//        }
//    }

//    /// <summary>
//    /// Converts between Type and String.
//    /// </summary>
//    public sealed class TypeTypeConverter : TypeConverter
//    {

//        /// <internalonly />
//        public override bool CanConvertFrom(Type sourceType)
//        {
//            return (sourceType == typeof(string));
//        }

//        /// <internalonly />
//        public override bool CanConvertTo(Type destinationType)
//        {
//            return (destinationType == typeof(string));
//        }

//        /// <internalonly />
//        public override object ConvertFrom(object value)
//        {
//            if (value is string)
//            {
//                string name = (string)value;
//                if (name.IndexOf(",") > 0)
//                {
//                    return Type.GetType(name, /* throwOnError */ true, /* ignoreCase */ false);
//                }
//                else
//                {
//                    Type appType = Application.Current.GetType();

//                    if (name.IndexOf(".") < 0)
//                    {
//                        name = appType.Namespace + "." + name;
//                    }
//                    return appType.Assembly.GetType(name, /* throwOnError */ true);
//                }
//            }
//            return base.ConvertFrom(value);
//        }

//        /// <internalonly />
//        public override object ConvertTo(object value, Type destinationType)
//        {
//            if (destinationType == typeof(string))
//            {
//                return ((Type)value).FullName;
//            }
//            return base.ConvertTo(value, destinationType);
//        }
//    }


//    /// <summary>
//    /// Converts between Type and String.
//    /// </summary>
//    public sealed class WindowCommandTypeConverter : TypeConverter
//    {

//        /// <internalonly />
//        public override bool CanConvertFrom(Type sourceType)
//        {
//            return (sourceType == typeof(string));
//        }

//        /// <internalonly />
//        public override bool CanConvertTo(Type destinationType)
//        {
//            return (destinationType == typeof(WindowCommand));
//        }

//        /// <internalonly />
//        public override object ConvertFrom(object value)
//        {
//            if (value is string)
//            {
//                return (WindowCommand)Enum.Parse(typeof(WindowCommand), (string)value, true);
//            }
//            return base.ConvertFrom(value);
//        }

//        /// <internalonly />
//        public override object ConvertTo(object value, Type destinationType)
//        {
//            if (destinationType == typeof(WindowCommand))
//            {
//                return Enum.GetName(typeof(WindowCommand), value);
//            }
//            return base.ConvertTo(value, destinationType);
//        }
//    }


//    public class LayoutGroupComparer : EqualityComparer<LayoutGroup>
//    {
//        public override bool Equals(LayoutGroup x, LayoutGroup y)
//        {
//            return x.Name.Equals(y.Name, StringComparison.CurrentCultureIgnoreCase);
//        }

//        public override int GetHashCode(LayoutGroup obj)
//        {
//            return int.MinValue;
//        }
//    }

//    /// <summary>
//    /// Ideal Class Implementation but we need to wait for Bugs to be fixed and maybe to be
//    /// able to derive from DependencyObject class
//    /// </summary>
//    public enum DisplayMode
//    {
//        Exclusive,
//        Inclusive
//    }

//    public enum WndCommand
//    {
//        Open,
//        Close,
//        OpenClose
//    }

//    public class WndGroup
//    {
//        public String Name { get; set; }
//        public DisplayMode Mode { get; set; }
//    }

//    public class WndCommandManager
//    {
//        public static object GetCmdHandled(DependencyObject element)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            return element.GetValue(CmdHandledProperty);
//        }

//        public static void SetCmdHandled(DependencyObject element, object value)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            element.SetValue(CmdHandledProperty, value);
//        }

//        public static readonly DependencyProperty CmdHandledProperty = null;

//        public static object GetCmdBinding(DependencyObject element)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            return element.GetValue(CmdBindingProperty);
//        }

//        public static void SetCmdBinding(DependencyObject element, object value)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            element.SetValue(CmdBindingProperty, value);
//        }

//        public static readonly DependencyProperty CmdBindingProperty = null;

//        public static object GetCmd(DependencyObject element)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            return element.GetValue(CmdProperty);
//        }

//        public static void SetCmd(DependencyObject element, object value)
//        {
//            if (element == null)
//            {
//                throw new ArgumentNullException("element");
//            }
//            element.SetValue(CmdProperty, value);
//        }

//        public static readonly DependencyProperty CmdProperty = null;

//        static WndCommandManager()
//        {
//            CmdBindingProperty = DependencyProperty.RegisterAttached("CmdBinding", typeof(UICmdBinding), typeof(WndCommandManager), new PropertyMetadata(new PropertyChangedCallback(OnCmdBindingChanged)));
//            CmdProperty = DependencyProperty.RegisterAttached("CmdBinding", typeof(UICmd), typeof(WndCommandManager), new PropertyMetadata(new PropertyChangedCallback(OnCmdChanged)));
//            CmdHandledProperty = DependencyProperty.RegisterAttached("CmdBinding", typeof(Boolean), typeof(WndCommandManager), null);
//        }

//        static void OnCmdBindingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
//        {
//        }

//        static void OnCmdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
//        {
//        }
//    }

//    /// <summary>
//    /// Can't derive from DependencyObject so ...
//    /// </summary>
//    public class UICmdBinding : Control
//    {
//        public Type Sink
//        {
//            get { return (Type)GetValue(SinkProperty); }
//            set { SetValue(SinkProperty, value); }
//        }

//        // Using a DependencyProperty as the backing store for Sink.  This enables animation, styling, binding, etc...
//        public static readonly DependencyProperty SinkProperty =
//            DependencyProperty.Register("Sink", typeof(Type), typeof(UICmdBinding), null);

//        public String Group
//        {
//            get { return (String)GetValue(GroupProperty); }
//            set { SetValue(GroupProperty, value); }
//        }

//        // Using a DependencyProperty as the backing store for Group.  This enables animation, styling, binding, etc...
//        public static readonly DependencyProperty GroupProperty =
//            DependencyProperty.Register("Group", typeof(String), typeof(UICmdBinding), null);
//    }

//    /// <summary>
//    /// Can't derive from DependencyObject so ...
//    /// </summary>
//    public class UICmd : Control
//    {
//        public Type Target
//        {
//            get { return (Type)GetValue(TargetProperty); }
//            set { SetValue(TargetProperty, value); }
//        }

//        // Using a DependencyProperty as the backing store for Sink.  This enables animation, styling, binding, etc...
//        public static readonly DependencyProperty TargetProperty =
//            DependencyProperty.Register("Target", typeof(Type), typeof(UICmd), null);

//        public WndCommand Mode
//        {
//            get { return (WndCommand)GetValue(ModeProperty); }
//            set { SetValue(ModeProperty, value); }
//        }

//        // Using a DependencyProperty as the backing store for Group.  This enables animation, styling, binding, etc...
//        public static readonly DependencyProperty ModeProperty =
//            DependencyProperty.Register("Group", typeof(WndCommand), typeof(UICmd), null);
//    }
//}
